package com.str.intro;
public class ImmutableString implements MyString {
    
  private char[] array; 

// Constructors  
  public ImmutableString()
  { array = new char[0]; }
  
  public ImmutableString(char[] that) { 
    array = new char[that.length];
    for (int i = 0; i < that.length; i++)
	  array[i] = that[i]; 
  }  

// Accessors
  public int length()
  { return array.length; }
		
  public char charAt(int i) { 
    if (i < 0 || i >= array.length)
      throw new IndexOutOfBoundsException();
    return array[i];
  }
		
  public boolean equals(MyString that) {
  	ImmutableString other = (ImmutableString) that;
  	if (array.length != other.length())
  	  return false;
  	for (int i = 0; i < array.length; i++)
  	  if (array[i] != other.array[i])
  	    return false;
  	return true;
  }
		
  public int compareTo(MyString that) {
  	ImmutableString other = (ImmutableString) that;
  	int len1 = array.length;
  	int len2 = other.length();
    for (int i = 0; i < Math.min(len1, len2); i++) {
      int comp = array[i] - other.array[i];
      if (comp != 0) return comp;
    }
    if (len1 > len2) return +1;
    else if (len1 < len2) return -1;
    else return 0; 
  }
		
  public MyString substring(int i, int j) {
  	if (i < 0 || i >= array.length || 
  	    j < 0 || j >= array.length || i > j )
      throw new IndexOutOfBoundsException();
    int len = j - i;
    char[] newArray = new char[len];
    for (int k = 0; k < len; k++)
      newArray[k] = array[i + k];
    return new ImmutableString(newArray);
  }
		
  public MyString concat(MyString that) {
  	ImmutableString other = (ImmutableString) that;
    int len = array.length + other.length();
  	char[] newArray = new char[len];
  	int i = 0, j = 0;
  	while (j < array.length)
  	  newArray[i++] = array[j++];
  	j = 0;
  	while (j < other.length())
  	  newArray[i++] = other.array[j++];
  	return new ImmutableString(newArray);
  }
  
  public String toString()
  { return new String(array); }
  
  public static void main(String[] args) {
    char[] a = {'H', 'e', 'l', 'l', 'o'};
    char[] b = {'G', 'o', 'o', 'd', 'b', 'y', 'e'};
    
    MyString s1 = new ImmutableString(a);
    MyString s2 = new ImmutableString(b);
    
    System.out.println("s1 = " + s1);
    System.out.println("s2 = " + s2);

    System.out.println("s1.length() = " + s1.length());
    System.out.println("s2.length() = " + s2.length());
    System.out.println("s1.charAt(1) = " + s1.charAt(1));
    System.out.println("s2.charAt(3) = " + s2.charAt(3)); 
        
    System.out.println("s1.equals(s1) = " + s1.equals(s1));
    System.out.println("s1.equals(s2) = " + s1.equals(s2));
    System.out.println("s2.equals(s1) = " + s2.equals(s1));
    System.out.println("s2.equals(s2) = " + s2.equals(s2));   
    System.out.println("s1.compareTo(s2) = " + s1.compareTo(s2));
    System.out.println("s2.compareTo(s1) = " + s2.compareTo(s1));  

    System.out.println("s1.substring(2, 4) = " + s1.substring(2, 4));
    System.out.println("s2.substring(3, 6) = " + s2.substring(3, 6));
    System.out.println("s1.concat(s2) = " + s1.concat(s2));
    System.out.println("s2.concat(s1) = " + s2.concat(s1));
  }  
}
